package com.success.task.web.lucene.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;

import com.success.task.web.lucene.interfaces.IndexCreateInterface;

/**
 * @author shimei
 * @version 2012-2-16 IndexCreate.java
 * 索引创建类
 */
public class FolderIndexCreator implements IndexCreateInterface {

	/**
	 * 被索引的内容
	 */
	public static final String INDEX_NAME= "contents";
	
	public static final String INDEX_FILE_NAME = "fileName";
	/**
	 * 被索引的路径
	 */
	public static final String INDEX_RESULT_PATH = "path";
	
	public static final String INDEX_FILE_SIZE = "size";
	
	/**
	 * 默认索引目录
	 */
	public static final String DEFAULT_INDEX_DIRS = "D:\\paoding\\testfiles";
	
	/**
	 * 默认索引文件存放目录
	 */
	public static final String DEFAULT_DATA_DIRS = "D:\\paoding\\tempdata";
	
	/**
	 * 被索引的内容 提供setter可通过spring 灵活配置
	 */
	private String indexContents = INDEX_NAME;
	
	/**
	 * 被索引的路径  提供setter可通过spring 灵活配置
	 */
	private String indexResultPath = INDEX_RESULT_PATH;
	
	/**
	 * 默认索引目录 提供setter可以通过spring 灵活配置
	 */
	private static  String indexDirs = DEFAULT_INDEX_DIRS;
	
	/**
	 * 默认索引文件存放目录 提供setter可以通过spring 灵活配置
	 */
	private String dataDirs = DEFAULT_DATA_DIRS;
	
	/**
	 * 索引目录File对象
	 */
	private File  indexDir = null;
	
	/**
	 * 目标目录File对象
	 */
    private File  dataDir  = null;
    
    /**
     * 索引书写者
     */
    private static IndexWriter indexWriter = null;
    
    /**
     * 词法分析器
     */
    private static Analyzer analyzer = null;
	
    /**
     * 默认使用庖丁词法分析器，支持中文
     */
    private String analyzerName = "net.paoding.analysis.analyzer.PaodingAnalyzer";
    
    /**
     * 构造方法
     */
    
    private String luceneEncode = "GBK";
    
    public FolderIndexCreator () {};
    
	public void init() throws CorruptIndexException, LockObtainFailedException, IOException ,InstantiationException ,IllegalAccessException ,ClassNotFoundException{
		if (null == indexDir) {
    		indexDir = new File(FolderIndexCreator.getIndexDirs());
    	} if (null == dataDir) {
    		dataDir = new File(this.getDataDirs());
    	} if(null == indexWriter) {
    		//indexWriter = new IndexWriter(FSDirectory.getDirectory(dataDir), analyzer, true);
    	} if (null == analyzer) {
			analyzer = (Analyzer)Class.forName(analyzerName).newInstance();
    	}
    }
    
	
	public void createIndex() throws CorruptIndexException, LockObtainFailedException,IOException {
		try {
			init();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long startTime = new Date().getTime(); 
		indexWriter = new IndexWriter(FSDirectory.getDirectory(dataDir), analyzer, true);
		indexWriter.setMaxFieldLength(10000);
		index(indexWriter, indexDir);
		indexWriter.optimize(); 
		indexWriter.close(); 
		long endTime = new Date().getTime(); 
        System.out.println("It takes " + (endTime - startTime) 
	         + " milliseconds to create index for the files in directory "
	         + indexDir.getPath());     
	}
	
	
	public void index(IndexWriter indexWriters,File root) throws FileNotFoundException,IOException {
		if (root.canRead()) {  
            if (root.isDirectory()) {  
	                File[] files = root.listFiles();  
	                if (files.length != 0) {  
	                    for (int i = 0; i < files.length; i++) {  
	                    	index(indexWriters, files[i]);  
	                    }  
	                }  
            } else {  
                 InputStream in = new FileInputStream(root);  
                 byte b[] = new byte[in.available()];  
                 in.read(b);  
                 String content = new String(b, luceneEncode);  
                 Document d = new Document();  
                 d.add(new Field(INDEX_FILE_NAME, root.getName(), Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS)); 
                 d.add(new Field(INDEX_NAME, content, Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));  
                 d.add(new Field(INDEX_RESULT_PATH, root.getAbsolutePath(),Field.Store.YES, Field.Index.UN_TOKENIZED));  
                 d.add(new Field(INDEX_FILE_SIZE, String.valueOf(root.length()),Field.Store.YES, Field.Index.UN_TOKENIZED));
                 d.add(new Field("indexType", String.valueOf(0),Field.Store.YES, Field.Index.UN_TOKENIZED));
                 indexWriters.addDocument(d);  
                 System.out.println("add file: " + root.getAbsolutePath());  
            }  
        }
	}
	
	
	public String getIndexContents() {
		return indexContents;
	}

	public void setIndexContents(String indexContents) {
		this.indexContents = indexContents;
	}

	public String getIndexResultPath() {
		return indexResultPath;
	}

	public void setIndexResultPath(String indexResultPath) {
		this.indexResultPath = indexResultPath;
	}

	public static String getIndexDirs() {
		return indexDirs;
	}

	public void setIndexDirs(String indexDirs) {
		FolderIndexCreator.indexDirs = indexDirs;
	}

	public String getDataDirs() {
		return dataDirs;
	}

	public void setDataDirs(String dataDirs) {
		this.dataDirs = dataDirs;
	}


	public static Analyzer getAnalyzer() {
		return analyzer;
	}

	public static void setAnalyzer(Analyzer analyzer) {
		FolderIndexCreator.analyzer = analyzer;
	}
	
	
	public String getLuceneEncode() {
		return luceneEncode;
	}

	public void setLuceneEncode(String luceneEncode) {
		this.luceneEncode = luceneEncode;
	}

	public void setAnalyzerName(String analyzerName) {
		this.analyzerName = analyzerName;
	}
	
	
//	public static void main(String [] args) {
//		FolderIndexCreator fi = new FolderIndexCreator();
//		try {
//			fi.createIndex();
//		} catch (CorruptIndexException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (LockObtainFailedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
}
